home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 029 (1987-08-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 029 (1987-08-15)(Ossowski, Stefan)(DE)(PD).adf / Robotroff / Robotroff.c < prev    next >
C/C++ Source or Header  |  1978-08-10  |  10KB  |  375 lines

  1. /*  :ts=8 bk=0
  2.  *
  3.  * robotroff.c:        Insidious display hack.
  4.  *
  5.  * Leo L. Schwab            8703.17        (415)-456-6565
  6.  *
  7.  * Public Domain.  Reproduce at will.  However, the author would greatly
  8.  * appreciate it if:
  9.  *    1) All parts of the program are made available free of charge
  10.  *        (or for cost of media),
  11.  *    2) You don't use this in a commercial product unless you at least
  12.  *       tell me about it,
  13.  *    3) This notice and the author's name are preserved, even across
  14.  *        subsequent revisions (I want to be famous, you see).
  15.  *
  16.  * Naturally, you don't *have* to abide by these terms.  Just remember
  17.  * that if you do violate them, it means you are morally bankrupt.  You
  18.  * wouldn't want people to think that about you, would you?
  19.  *
  20. *************************************************************************
  21.             A few notes on the code:
  22.  
  23.     Bits of it are extremely messy.  Some of it looks unnecessary or
  24. wrong.  As it turns out, this program works as written.  Hope you can
  25. understand the code; some of it is instructive.  Watch out for ternary
  26. operators; I've used quite a few of them.
  27.  
  28.     Since this is supposed to be a background display hack, it was
  29. important to me to make it as small as I could and still do interesting
  30. things.  This meant leaving out a couple of features I would have liked.
  31. It would have been nice to have an explosion noise when the grunt or
  32. enforcer ran into the mouse.  I was also thinking about arranging things
  33. so that, if you plugged in a joystick at port 2 and tilted it around, you
  34. could shoot the enemy sprites.  These are ideas that the more ambitious
  35. among you might want to add in.  Some of you may have even more insidious
  36. ideas.  Go right ahead.
  37.  
  38.     I encountered some odd behavior in the system I never noticed
  39. before.  For example, if you AbortIO() an I/O request, the reply gets posted
  40. to your reply port, and the signal you might Wait() on gets set.  WaitIO()
  41. does not clear this signal apparently; I had to do it myself.
  42.  
  43.     Also, when moving the mouse pointer with false InputEvents, I
  44. noticed that the mouse pointer, even in a 200-line screen, assumes it's in
  45. a 400-line screen, and therefore a "movement" of 2 results in an actual
  46. pointer movement of 1.  Odd.  Does anyone have an explanation for this?
  47.  
  48.     I tried to write the code in a such a way that it *should* work on
  49. an interlaced screen, as well as one that's been 'morerows'ed.  However,
  50. since 'morerows' causes overscan, which tromps sprite DMA, this may not
  51. work on an overscan screen.  Oddly enough, it also seems to work with any
  52. combination of screens, no matter their arrangement.  
  53.  
  54.     I had fun writing this program.  I hope you like it at least as
  55. much as you liked Oing.
  56.  
  57.     "If you've enjoyed this program just half as much as I've enjoyed
  58. writing it, then I'll have enjoyed it twice as much as you."
  59.  
  60.                     Have fun,
  61.                     Leo L. Schwab
  62.  
  63. *************************************************************************/
  64.  
  65. #include <ctype.h>
  66. #include <exec/types.h>
  67. #include <exec/alerts.h>
  68. #include <intuition/intuition.h>
  69. #include <graphics/sprite.h>
  70. #include <devices/input.h>
  71. #include "robotroff.h"
  72.  
  73.  
  74. /*  We're just opening this to get a pointer to the WorkBench ViewPort  */
  75. struct NewWindow windef = {
  76.     0, 0, 3, 10,
  77.     -1, -1,
  78.     NULL,
  79.     NULL,
  80.     NULL, NULL,
  81.     NULL,
  82.     NULL, NULL, 0, 0, 0, 0,
  83.     WBENCHSCREEN
  84. };
  85.  
  86. struct MsgPort        *ioport, *timeport, *cmdport;
  87. struct IOStdReq        *ioreq;
  88. struct timerequest    *timereq;
  89. struct control        *ctl;
  90. struct InputEvent    mouse;
  91. struct SimpleSprite    spr;
  92. struct Preferences    prefs;
  93. struct Screen        *wbs;
  94. struct Window        *win;
  95. long            sprnum = -1;
  96. int            wide, high;
  97. void            *vp;
  98. void            *IntuitionBase, *GfxBase;
  99. /*  I take so many liberties with void *'s, it's scary.  */
  100.  
  101.  
  102. main (ac, av)
  103. char **av;
  104. {
  105.     void *daemon;
  106.  
  107.     if (daemon = FindPort (PORTNAME))
  108.         reconfigure (ac, av, daemon);
  109.     else {
  110.         dodaemon (ac, av);
  111.         postmessage ("Robotroff daemon terminated.");
  112.     }
  113.  
  114.     closestuff ();
  115. }
  116.  
  117. dodaemon (ac, av)
  118. char **av;
  119. {
  120.     /*
  121.      * cmdport in this context means the port at which commands arrive
  122.      * for the daemon to act on.
  123.      */
  124.     register struct control *msg;
  125.     long csig, tsig, signals;
  126.     int hw = DEFAULTHIGHWATER, lw = DEFAULTLOWATER, now = 0;
  127.     void *me, *oldms;
  128.  
  129.     openstuff ();
  130.     rnd ((short) -VBeamPos());    /*  Seed generator  */
  131.     me = FindTask (NULL);
  132.  
  133.     /*  Parse command args  */
  134.     if (ac)
  135.         while (++av, --ac) {
  136.             if (!strncmp (*av, "-h", 2)) {
  137.                 hw = atoi (&(*av)[2]);
  138.                 if (hw <= 0)
  139.                     hw = DEFAULTHIGHWATER;
  140.             } else if (!strncmp (*av, "-l", 2)) {
  141.                 lw = atoi (&(*av)[2]);
  142.                 if (lw <= 0)
  143.                     lw = DEFAULTLOWATER;
  144.             } else if (!strncmp (*av, "-p", 2))
  145.                 SetTaskPri (me, (long) atoi (&(*av)[2]));
  146.             else if (!strcmp (*av, "-i"))
  147.                 now = 1;
  148.         }
  149.     if (hw < lw)    /*  hw time must not be shorter than lw time  */
  150.         lw = hw;
  151.  
  152.     tsig = TIMESIG;
  153.     csig = CMDSIG;
  154.     while (1) {
  155.         if (now) {
  156.             now = 0;
  157.             goto dosomething;
  158.         }
  159.  
  160.         timereq -> tr_time.tv_secs = rnd (hw-lw+1) + lw;
  161.         timereq -> tr_time.tv_micro = 0;
  162.  
  163.         SendIO (timereq);
  164.         signals = Wait (tsig | csig);
  165.  
  166.         if (signals & csig) {
  167.             /*  Command from another task (user)  */
  168.             msg = GetMsg (cmdport);
  169.             AbortIO (timereq);
  170.             WaitIO (timereq);
  171.             /*
  172.              * The I/O reply causes a signal to be 
  173.              * raised, which screws things up.  So
  174.              * we clear it.
  175.              */
  176.             Wait (tsig);
  177.  
  178.             if (msg -> actions & SUICIDE) {
  179.                 ReplyMsg (msg);
  180.                 break;
  181.             }
  182.             if (msg -> actions & SETHIGH)
  183.                 hw = msg -> highwater;
  184.             if (msg -> actions & SETLOW)
  185.                 lw = msg -> lowater;
  186.             if (hw < lw)
  187.                 lw = hw;
  188.             if (msg -> actions & SETPRI)
  189.                 SetTaskPri (me, (long) msg -> newpri);
  190.             if (msg -> actions & DOSOMETHING)
  191.                 now = 1;
  192.             ReplyMsg (msg);
  193.         }
  194.  
  195.         if (signals & tsig) {
  196.             /*  Timer went off, time to do something weird  */
  197.             WaitIO (timereq);
  198. dosomething:
  199.             switch (rnd (5)) {
  200.             case 0:  case 1:
  201.                 dohulk ();
  202.                 break;
  203.             case 2:  case 3:
  204.                 dogrunt ();
  205.                 break;
  206.             case 4:
  207.                 enforce ();
  208.             }
  209.         }
  210.     }
  211. }
  212.  
  213. reconfigure (ac, av, daemonport)
  214. char **av;
  215. void *daemonport;
  216. {
  217.     /*
  218.      * cmdport in this context means the reply port for commands to
  219.      * the daemon.
  220.      */
  221.  
  222.     if (ac < 2)    /*  Nothing to do  */
  223.         return;
  224.  
  225.     /*  In order to use die(), we have to open Intuition.  */
  226.     if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
  227.         Alert (AG_OpenLib | AO_Intuition, 0L);
  228.         closestuff ();
  229.         exit (20);
  230.     }
  231.     GetPrefs (&prefs, (long) sizeof (prefs));
  232.  
  233.     if (!(cmdport = CreatePort (NULL, NULL)))
  234.         die ("Can't create command reply port.");
  235.  
  236.     if (!(ctl = CreateExtIO (cmdport, (long) sizeof (*ctl))))
  237.         die ("Can't create command block.");
  238.  
  239.     /*  Parse command line args  */
  240.     while (++av, --ac) {
  241.         if (!strncmp (*av, "-h", 2)) {
  242.             ctl -> highwater = atoi (&(*av)[2]);
  243.             if (ctl -> highwater <= 0)
  244.                 ctl -> highwater = DEFAULTHIGHWATER;
  245.             ctl -> actions |= SETHIGH;
  246.         } else if (!strncmp (*av, "-l", 2)) {
  247.             ctl -> lowater = atoi (&(*av)[2]);
  248.             if (ctl -> lowater <= 0)
  249.                 ctl -> lowater = DEFAULTLOWATER;
  250.             ctl -> actions |= SETLOW;
  251.         } else if (!strncmp (*av, "-p", 2)) {
  252.             ctl -> newpri = atoi (&(*av)[2]);
  253.             ctl -> actions |= SETPRI;
  254.         } else if (!strcmp (*av, "-i"))
  255.             ctl -> actions |= DOSOMETHING;
  256.         else if (!strcmp (*av, "-kill"))
  257.             ctl -> actions |= SUICIDE;
  258.     }
  259.  
  260.     /*  Send command to daemon  */
  261.     PutMsg (daemonport, ctl);
  262.     WaitPort (cmdport);
  263.     GetMsg (cmdport);
  264. }
  265.  
  266. openstuff ()
  267. {
  268.     if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
  269.         Alert (AG_OpenLib | AO_Intuition, 0L);
  270.         closestuff ();
  271.         exit (20);
  272.     }
  273.     GetPrefs (&prefs, (long) sizeof (prefs));
  274.  
  275.     if (!(GfxBase = OpenLibrary ("graphics.library", 0L)))
  276.         die ("Art shop closed.");
  277.  
  278.     /*  Set up a few environment things based on screen info  */
  279.     if (!(win = OpenWindow (&windef)))
  280.         die ("Window painted shut.");
  281.     vp = ViewPortAddress (win);
  282.     wbs = win -> WScreen;
  283.     CloseWindow (win);  win = 0;
  284.     high = wbs -> Height;
  285.     wide = wbs -> Width;
  286.     if (wbs -> ViewPort.Modes & HIRES)
  287.         wide /= 2;
  288.     if (wbs -> ViewPort.Modes & LACE)
  289.         high /= 2;
  290.  
  291.     if ((sprnum = GetSprite (&spr, 2L)) < 0)
  292.         die ("Couldn't get sprite.");
  293.  
  294.     if (!(cmdport = CreatePort (PORTNAME)))
  295.         die ("Can't create command port.");
  296.  
  297.     if (!(timeport = CreatePort (NULL, NULL)))
  298.         die ("Can'r create time port.");
  299.  
  300.     if (!(timereq = CreateExtIO (timeport, (long) sizeof (*timereq))))
  301.         die ("Can't make timer I/O.");
  302.     if (OpenDevice (TIMERNAME, UNIT_VBLANK, timereq, 0L)) {
  303.         timereq -> tr_node.io_Device = 0;
  304.         die ("Can't open timer device.");
  305.     }
  306.     timereq -> tr_node.io_Command = TR_ADDREQUEST;
  307.  
  308.     if (!(ioport = CreatePort (NULL, NULL)))
  309.         die ("Can't create I/O port.");
  310.  
  311.     if (!(ioreq = CreateStdIO (ioport)))
  312.         die ("Can't make I/O request.");
  313.     if (OpenDevice ("input.device", 0L, ioreq, 0L)) {
  314.         ioreq -> io_Device = 0;
  315.         die ("Can't generate input.");
  316.     }
  317.     ioreq -> io_Command = IND_WRITEEVENT;
  318.     ioreq -> io_Flags = 0;
  319.     ioreq -> io_Length = sizeof (struct InputEvent);
  320.     ioreq -> io_Data = (APTR) &mouse;
  321. }
  322.  
  323. closestuff ()
  324. {
  325.     if (ioreq) {
  326.         if (ioreq -> io_Device)
  327.             CloseDevice (ioreq);
  328.         DeleteStdIO (ioreq);
  329.     }
  330.     if (timereq) {
  331.         if (timereq -> tr_node.io_Device)
  332.             CloseDevice (timereq);
  333.         DeleteExtIO (timereq, (long) sizeof (*timereq));
  334.     }
  335.     if (ctl)        DeleteExtIO (ctl, (long) sizeof (*ctl));
  336.     if (cmdport)        DeletePort (cmdport);
  337.     if (ioport)        DeletePort (ioport);
  338.     if (timeport)        DeletePort (timeport);
  339.     if (sprnum >= 0)    FreeSprite (sprnum);
  340.     if (win)        CloseWindow (win);
  341.     if (GfxBase)        CloseLibrary (GfxBase);
  342.     if (IntuitionBase)    CloseLibrary (IntuitionBase);
  343. }
  344.  
  345. die (str)
  346. char *str;
  347. {
  348.     postmessage (str);
  349.     closestuff ();
  350.     exit (10);
  351. }
  352.  
  353. postmessage (str)
  354. char *str;
  355. {
  356.     if (win)    CloseWindow (win);    /*  Should never happen  */
  357.  
  358.     windef.TopEdge = 0;
  359.     windef.Height = 10;
  360.     windef.Width = 8 + strlen (str) *
  361.             (prefs.FontHeight == TOPAZ_SIXTY ? 10 : 8);
  362.     windef.LeftEdge = (640 - windef.Width) / 2;
  363.     windef.DetailPen = 1;
  364.     windef.BlockPen = 3;
  365.     windef.Flags |= ACTIVATE;
  366.     windef.Title = (UBYTE *) str;
  367.  
  368.     if (!(win = OpenWindow (&windef)))
  369.         /*  Crash system and let user worry about it  */
  370.         Alert (AN_OpenWindow, 0L);
  371.  
  372.     Delay (200L);
  373.     CloseWindow (win);  win = 0;
  374. }
  375.